//
//  NemoWhiteboardView.m
//  NemoSDKDemo
//
//  Created by NemoSDKDemo on 19/5/27.
//  Copyright © 2019 JackYang. All rights reserved.
//

#import "NemoWhiteboardView.h"
#import "UIColor+XYColor.h"
#import <OpenGLES/ES2/glext.h>


#define ONE_PIXEL_DISTANCE (1.0f/[UIScreen mainScreen].scale)


#pragma mark - WhiteboardView;
@interface NemoWhiteboardView () <GLKViewDelegate>
{
    EAGLContext *context;
    BOOL bRedrawing;
    CGFloat _canvasAspect;
}

@property (nonatomic, assign) NSInteger selectedTool;
@property (nonatomic, assign) NSInteger selectedColor;

@property (nonatomic, strong) DrawingBezierCommand *localCommand;
@property (nonatomic, strong) NSMutableArray *drawingRemoteCommands;
@property (nonatomic, strong) NSMutableArray *completedCommands;
@property (nonatomic, strong) NSMutableArray *undoedCommands;

@end

@implementation NemoWhiteboardView

@synthesize whiteboardDelegate;

#pragma mark - handle gestures inherited from baseVideoView
-(void)onZoom:(UIPinchGestureRecognizer *)gesture
{
    if (gesture.state == UIGestureRecognizerStateBegan){
        
    } else if (gesture.state == UIGestureRecognizerStateChanged){
    }
    else
    {
    }
    
    [gesture setScale:1];
}

-(void)onPan:(UIPanGestureRecognizer *)gesture
{
    if (_status != NemoWhiteboardStatus_Opened)
        return;
    
    CGPoint location = [gesture locationInView:_drawingView];
    CGPoint locationGL = [self glPointFromViewPoint:location];
    
    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        self.localCommand = [[DrawingBezierCommand alloc]initWithSequeceId:0];
        _localCommand.lineColor = [self colorForColorIndex:_selectedColor];
        if (self.selectedTool == 1)
        {
            CGFloat width = [self viewWidthFromStandardWidth:2];
            width = [self glWidthFromViewWidth:width];
            _localCommand.lineWidth = width;
        }
        else if (_selectedTool == 2)
        {
            CGFloat width = [self viewWidthFromStandardWidth:15];
            width = [self glWidthFromViewWidth:width];
            _localCommand.lineWidth = width;
            CGFloat red, green, blue, alpha;
            [_localCommand.lineColor getRed:&red green:&green blue:&blue alpha:&alpha];
            _localCommand.lineColor = [UIColor colorWithRed:red green:green blue:blue alpha:0.5];
        }
        else
        {
            CGFloat width = [self viewWidthFromStandardWidth:50];
            width = [self glWidthFromViewWidth:width];
            _localCommand.lineWidth = width;
            _localCommand.lineColor = [UIColor clearColor];
            //                _localCommand.isErasered = YES;
        }
        
        [_localCommand setAspect:_drawingView.bounds.size.width/_drawingView.bounds.size.height];
        [_localCommand setInitialPoint:locationGL];
    }
    else if (gesture.state == UIGestureRecognizerStateChanged)
    {
        BOOL needToDraw = [_localCommand moveToPoint:locationGL];
        if (needToDraw)
        {
            [_drawingView setNeedsDisplay];
            
            CGFloat width = [self viewWidthFromGlWidth:_localCommand.lineWidth];
            width = [self standardWidthFromViewWidth:width];
            
            NSArray *trackPoints = [_localCommand getTrackPoints];
            BOOL isStart = (trackPoints.count <= 5);
            NSMutableArray *points = [[NSMutableArray alloc] initWithCapacity:3];
            NSInteger pointCountToGet = isStart?5:3;
            for (NSInteger i=trackPoints.count-pointCountToGet; i< trackPoints.count ; i++)
            {
                NSValue *value = [trackPoints objectAtIndex:i];
                CGPoint point = [value CGPointValue];
                point = [self viewPointFromGlPoint:point];
                point = [self standardPointFromViewPoint:point];
                
                [points addObject:[NSValue valueWithCGPoint:point]];
            }
            
            [whiteboardDelegate didDrawLineInWhiteboard:self
                                                  Color:_localCommand.lineColor
                                                  width:width
                                                 points:points
                                                isStart:isStart
                                               isFinish:NO];
        }
    }
    else
    {
//        [_localCommand moveToPoint:locationGL];
        [_localCommand moveEnd];
        [_drawingView setNeedsDisplay];
        
        CGFloat width = [self viewWidthFromGlWidth:_localCommand.lineWidth];
        width = [self standardWidthFromViewWidth:width];
        
        NSArray *trackPoints = [_localCommand getTrackPoints];
        BOOL isStart = (trackPoints.count < 5);
        NSMutableArray *points = [[NSMutableArray alloc] initWithCapacity:3];
        NSInteger pointCountToGet = isStart?trackPoints.count:((trackPoints.count % 3)+1)%3;
        if (pointCountToGet > 0)
        {
            for (NSInteger i=trackPoints.count-pointCountToGet; i< trackPoints.count ; i++)
            {
                NSValue *value = [trackPoints objectAtIndex:i];
                CGPoint point = [value CGPointValue];
                point = [self viewPointFromGlPoint:point];
                point = [self standardPointFromViewPoint:point];
                
                [points addObject:[NSValue valueWithCGPoint:point]];
            }
        }
        else
        {
            CGPoint point = [self standardPointFromViewPoint:location];
            [points addObject:[NSValue valueWithCGPoint:point]];
        }
        
        [whiteboardDelegate didDrawLineInWhiteboard:self
                                              Color:_localCommand.lineColor
                                              width:width
                                             points:points
                                            isStart:isStart
                                           isFinish:YES];
    }
    
    [gesture setTranslation:CGPointZero inView:_drawingView];
}

- (void)onTap:(UITapGestureRecognizer *)gesture
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"whiteboard_tap" object:nil];
}
#pragma mark - IBActions
-(void)setSelectedTool:(NSInteger)selectedTool
{
    _selectedTool = selectedTool;

    _pencilBtn.alpha = (_selectedTool==1?1.0:0.2);
    _highlightBtn.alpha = (_selectedTool==2?1.0:0.2);
    _eraserBtn.alpha = (_selectedTool==3?1.0:0.2);
}

-(IBAction)tapToolBtn:(id)sender
{
    UIButton *button = sender;
    self.selectedTool = button.tag;
}

-(IBAction)tapColorBtn:(id)sender
{
    _colorContainer.hidden = NO;
    _buttonContainer.hidden = YES;
    
    _colorContainer.center = CGPointMake(208+_toolbarView.frame.size.width/2,
                                         _toolbarView.frame.size.height/2);
    
    [UIView animateWithDuration:0.3 animations:^{
        _colorContainer.center = CGPointMake(_toolbarView.frame.size.width/2,
                                             _toolbarView.frame.size.height/2);
    } completion:^(BOOL finished) {
    }];
}

-(IBAction)tapClearBtn:(id)sender;
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"清空白板" message:@"点击\"确定\"按钮将会清空白板中的所有内容" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:nil];
    [alertController addAction:cancel];
    UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self clear];
        [whiteboardDelegate didClearedInWhiteboard:self];
    }];
    [alertController addAction:confirm];
    
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    UIViewController *rootViewController1 = window.rootViewController;
    UIViewController *topViewController = [self topViewControllerWithRootViewController:rootViewController1];
    [topViewController presentViewController:alertController animated:YES completion:nil];
}

- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController{
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController *tabBarController = (UITabBarController *)rootViewController;
        return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
    } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController* navigationController = (UINavigationController*)rootViewController;
        return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
    } else if (rootViewController.presentedViewController) {
        UIViewController* presentedViewController = rootViewController.presentedViewController;
        return [self topViewControllerWithRootViewController:presentedViewController];
    } else {
        return rootViewController;
    }
}

-(void)setSelectedColor:(NSInteger)selectedColor
{
    _selectedColor = selectedColor;

    if (_selectedColor == 1)
    {
        [_colorBtn setImage:[UIImage imageNamed:@"yellow_color.png"] forState:UIControlStateNormal];
    }
    else if (_selectedColor == 2)
    {
        [_colorBtn setImage:[UIImage imageNamed:@"black_color.png"] forState:UIControlStateNormal];
    }
    else if (_selectedColor == 3)
    {
        [_colorBtn setImage:[UIImage imageNamed:@"blue_color.png"] forState:UIControlStateNormal];
    }
    else
    {
        [_colorBtn setImage:[UIImage imageNamed:@"red_color.png"] forState:UIControlStateNormal];
    }
}

-(IBAction)selectColor:(id)sender
{
    UIButton *button = sender;
    
    self.selectedColor = button.tag;
    
    _colorContainer.center = CGPointMake(_toolbarView.frame.size.width/2,
                                         _toolbarView.frame.size.height/2);
    
    [UIView animateWithDuration:0.3 animations:^{
        _colorContainer.center = CGPointMake(208+_toolbarView.frame.size.width/2,
                                             _toolbarView.frame.size.height/2);
    } completion:^(BOOL finished) {
        _colorContainer.hidden = YES;
        _buttonContainer.hidden = NO;
    }];
}

-(IBAction)cancelColorSelect:(id)sender
{
    _colorContainer.center = CGPointMake(_toolbarView.frame.size.width/2,
                                         _toolbarView.frame.size.height/2);
    
    [UIView animateWithDuration:0.3 animations:^{
        _colorContainer.center = CGPointMake(208+_toolbarView.frame.size.width/2,
                                             _toolbarView.frame.size.height/2);
    } completion:^(BOOL finished) {
        _colorContainer.hidden = YES;
        _buttonContainer.hidden = NO;
    }];
}

-(void)undoWhiteboard:(UIButton*)button
{
    DrawingBezierCommand *command = [_completedCommands lastObject];
    if (command)
    {
        [_undoedCommands addObject:command];
        [_completedCommands removeObject:command];
        bRedrawing = YES;
        [_drawingView setNeedsDisplay];

        [whiteboardDelegate didUndoInWhiteboard:self seqId:command.sequenceId];
    }
}

-(void)redoWhiteboard:(UIButton*)button
{
    DrawingBezierCommand *command = [_undoedCommands lastObject];
    if (command)
    {
        [_completedCommands addObject:command];
        [_undoedCommands removeObject:command];

        bRedrawing = YES;
        [_drawingView setNeedsDisplay];

        [whiteboardDelegate didRedoInWhiteboard:self seqId:command.sequenceId];
    }
}

#pragma mark - private functions
- (void)configDrawArea {
    _drawingView.delegate = self;
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    
    if (context) {
        _drawingView.opaque = NO;
        _drawingView.context = context;
        _drawingView.drawableDepthFormat = GLKViewDrawableDepthFormatNone;
        _drawingView.enableSetNeedsDisplay = YES;
        
        // Turn on antialiasing
        _drawingView.drawableMultisample = GLKViewDrawableMultisample4X;
        
        [EAGLContext setCurrentContext:context];
        
        bRedrawing = YES;
        [_drawingView setNeedsDisplay];
        
    } else [NSException raise:@"NSOpenGLES2ContextException" format:@"Failed to create OpenGL ES2 context"];
}

-(void)configUI
{
    _drawingContainer.layer.borderColor =  UIColor.black(0.2).CGColor;
    _drawingContainer.layer.borderWidth = ONE_PIXEL_DISTANCE;
    
    _colorContainer.hidden = YES;
    
    self.selectedTool = 1;
    self.selectedColor = 3;
}

/**************** Point GL <--> View  **************/
-(CGPoint)glPointFromViewPoint:(CGPoint)point
{
    CGPoint ret;
    
    CGSize size = _drawingView.bounds.size;
    
    ret.x = point.x/size.width * 2.0 - 1;
    ret.y = ((point.y/size.height) * 2.0 - 1) * -1;
    
    return  ret;
}

-(CGPoint)viewPointFromGlPoint:(CGPoint)point
{
    CGPoint ret;
    
    CGSize size = _drawingView.bounds.size;
    
    ret.x = (point.x+1) / 2.0 * size.width;
    ret.y = ((point.y * -1) + 1) / 2.0 * size.height;
    
    return  ret;
}

/************ Width GL <--> view ********************/
-(CGFloat)glWidthFromViewWidth:(CGFloat)width
{
    return width/_drawingView.bounds.size.width * 2.0;
}

-(CGFloat)viewWidthFromGlWidth:(CGFloat)width
{
    return width / 2.0 * _drawingView.bounds.size.width;
}

/*************** Point View <--> standard *************/
-(CGPoint)viewPointFromStandardPoint:(CGPoint)point
{
    CGPoint ret;
    
    ret.x = (point.x/1000) * _drawingView.bounds.size.width;
    ret.y = (point.y/1000) * _drawingView.bounds.size.height;
    
    return ret;
}

-(CGPoint)standardPointFromViewPoint:(CGPoint)point
{
    CGPoint ret;
    
    ret.x = (point.x/_drawingView.bounds.size.width) * 1000;
    ret.y = (point.y/_drawingView.bounds.size.height) * 1000;
    
    return ret;
}

/*************** Width View <--> standard *************/
-(CGFloat)viewWidthFromStandardWidth:(CGFloat)width
{
    return (width/1000) * _drawingView.bounds.size.width;
}


-(CGFloat)standardWidthFromViewWidth:(CGFloat)width
{
    return (width/_drawingView.bounds.size.width) * 1000;
}

-(UIColor*)colorForColorIndex:(NSInteger)index
{
    if (index == 1)
    {
        return [UIColor colorWithHexString:@"#FFC766"];
    }
    else if (index == 2)
    {
        return [UIColor colorWithHexString:@"#181818"];
    }
    else if (index == 3)
    {
        return [UIColor colorWithHexString:@"#2081BF"];
    }
    else
    {
        return [UIColor colorWithHexString:@"#FF6666"];
    }
}

-(void)appDidBecomeActive
{    
    bRedrawing = YES;
    [self.drawingView setNeedsDisplay];
}

-(void)registerNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appDidBecomeActive)
                                                 name:UIApplicationDidBecomeActiveNotification
                                               object:nil];
}

#pragma mark - life circles
-(void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(void)awakeFromNib
{
    [super awakeFromNib];
    self.completedCommands = [[NSMutableArray alloc] init];
    self.drawingRemoteCommands = [[NSMutableArray alloc] init];
    self.undoedCommands = [[NSMutableArray alloc] init];
    
    [self configDrawArea];
    [self configUI];
    
    [self registerNotifications];
    
    _canvasAspect = 16./9.;
    
    UIPinchGestureRecognizer *eaglViewPinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(onZoom:)];
    [self addGestureRecognizer:eaglViewPinch];
    
    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPan:)];
    panRecognizer.maximumNumberOfTouches = 1;
    [self addGestureRecognizer:panRecognizer];
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
    
    [self addGestureRecognizer:tap];
}

+ (NemoWhiteboardView *)whiteboardView{
    NemoWhiteboardView *whiteboardView = [[NSBundle mainBundle] loadNibNamed:@"NemoWhiteboardView" owner:nil options:nil].firstObject;
    whiteboardView.frame = [UIScreen mainScreen].bounds;
    whiteboardView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    return whiteboardView;
}

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.completedCommands = [[NSMutableArray alloc] init];
        self.drawingRemoteCommands = [[NSMutableArray alloc] init];
        self.undoedCommands = [[NSMutableArray alloc] init];
        
        [self configDrawArea];
        [self configUI];
    }

    return self;
}

-(void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    
    CGFloat radius = _toolbarView.frame.size.height/2;
    [_toolbarView.layer setCornerRadius:radius];
    [_toolbarView.layer setMasksToBounds:YES];
}

-(void)setIsFullScreen:(BOOL)isFullScreen
{
//    [super setIsFullScreen:isFullScreen];
    
    _toolbarView.hidden = !isFullScreen;
    if (isFullScreen)
    {
        bRedrawing = YES;
        [_drawingView setNeedsDisplay];
    }
}

#pragma mark - GLKView delegate to draw
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    if (bRedrawing)
    {
        CGFloat red, green, blue, alpha;
        [[UIColor clearColor] getRed:&red green:&green blue:&blue alpha:&alpha];
        glClearColor(red, green, blue, alpha);
        glClear(GL_COLOR_BUFFER_BIT);
        glFlush();
        
        if (_completedCommands) {
            for (int i=0; i< _completedCommands.count; i++)
            {
                DrawingBezierCommand *command = [_completedCommands objectAtIndex:i];
                [command redraw];
            }
        }
        bRedrawing = NO;
    }
    else
    {
        [_localCommand draw];
        
        for (DrawingBezierCommand *command in _drawingRemoteCommands)
        {
            if (!command.isSaveOnly)
            {
                [command draw];
            }
        }
        
        for (NSInteger i=_drawingRemoteCommands.count-1; i >=0; i--)
        {
            DrawingBezierCommand *command = [_drawingRemoteCommands objectAtIndex:i];
            if (command.finished)
            {
                NSLog(@"whiteboard line (%d) is drawn, remove it from drawing commands", command.sequenceId);
                [_drawingRemoteCommands removeObject:command];
            }
        }
    }
}

#pragma mark - Public functions
-(void)setStatus:(NemoWhiteboardStatus)status
{
    NSLog(@"%s, set whiteboard %@ status %ld", __FUNCTION__, self, (long)status);
    _status = status;
    if(status == NemoWhiteboardStatus_Opening)
    {
        _dimingView.hidden = NO;
    }
    else
    {
        _dimingView.hidden = YES;
    }
}

-(void)setCanvasAspect:(CGFloat)aspect
{
    if (_canvasAspect == aspect)
        return;
    
    _canvasAspect = aspect;
    
    [_drawingContainer removeConstraints:_drawingContainer.constraints];
    for (NSLayoutConstraint *constraint in self.constraints)
    {
        if ([constraint.firstItem isEqual:_drawingContainer] ||
            [constraint.secondItem isEqual:_drawingContainer])
        {
            [self removeConstraint:constraint];
        }
    }
    
    if (_canvasAspect > self.bounds.size.width/self.bounds.size.height)
    {
        [self addConstraints:@[
                               [NSLayoutConstraint constraintWithItem:_drawingContainer
                                                            attribute:NSLayoutAttributeWidth
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:_drawingContainer
                                                            attribute:NSLayoutAttributeHeight
                                                           multiplier:_canvasAspect
                                                             constant:0],
                               [NSLayoutConstraint constraintWithItem:_drawingContainer
                                                            attribute:NSLayoutAttributeLeading
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:NSLayoutAttributeLeading
                                                           multiplier:1.0
                                                             constant:0],
                               [NSLayoutConstraint constraintWithItem:_drawingContainer
                                                            attribute:NSLayoutAttributeTrailing
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:NSLayoutAttributeTrailing
                                                           multiplier:1.0
                                                             constant:0],
                               [NSLayoutConstraint constraintWithItem:_drawingContainer
                                                            attribute:NSLayoutAttributeCenterY
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:NSLayoutAttributeCenterY
                                                           multiplier:1.0
                                                             constant:0]
                               
                               ]];
    }
    else
    {
        [self addConstraints:@[
                               [NSLayoutConstraint constraintWithItem:_drawingContainer
                                                            attribute:NSLayoutAttributeWidth
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:_drawingContainer
                                                            attribute:NSLayoutAttributeHeight
                                                           multiplier:_canvasAspect
                                                             constant:0],
                               [NSLayoutConstraint constraintWithItem:_drawingContainer
                                                            attribute:NSLayoutAttributeTop
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:NSLayoutAttributeTop
                                                           multiplier:1.0
                                                             constant:0],
                               [NSLayoutConstraint constraintWithItem:_drawingContainer
                                                            attribute:NSLayoutAttributeBottom
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:NSLayoutAttributeBottom
                                                           multiplier:1.0
                                                             constant:0],
                               [NSLayoutConstraint constraintWithItem:_drawingContainer
                                                            attribute:NSLayoutAttributeCenterX
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:NSLayoutAttributeCenterX
                                                           multiplier:1.0
                                                             constant:0]
                               
                               ]];
    }
    
    [_drawingContainer addConstraints:@[
                                        [NSLayoutConstraint constraintWithItem:_drawingView
                                                                     attribute:NSLayoutAttributeTop
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:_drawingContainer
                                                                     attribute:NSLayoutAttributeTop
                                                                    multiplier:1.0
                                                                      constant:0],
                                        [NSLayoutConstraint constraintWithItem:_drawingView
                                                                     attribute:NSLayoutAttributeLeading
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:_drawingContainer
                                                                     attribute:NSLayoutAttributeLeading
                                                                    multiplier:1.0
                                                                      constant:0],
                                        [NSLayoutConstraint constraintWithItem:_drawingView
                                                                     attribute:NSLayoutAttributeTrailing
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:_drawingContainer
                                                                     attribute:NSLayoutAttributeTrailing
                                                                    multiplier:1.0
                                                                      constant:0],
                                        [NSLayoutConstraint constraintWithItem:_drawingView
                                                                     attribute:NSLayoutAttributeBottom
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:_drawingContainer
                                                                     attribute:NSLayoutAttributeBottom
                                                                    multiplier:1.0
                                                                      constant:0],
                                        ]];
}

-(void)drawLineWithSequenceId:(int)seqId
                        color:(UIColor*)color
                        width:(CGFloat)width
                       points:(NSArray*)pointArray
                     lineFlag:(RemoteLineFlag)flag
{
    NSLog(@"%s, seqId=%d, points:%@", __FUNCTION__, seqId, pointArray);
    
    DrawingBezierCommand *specifiedCommand = nil;
    for (DrawingBezierCommand *command in _drawingRemoteCommands)
    {
        if (command.sequenceId == seqId)
        {
            specifiedCommand = command;
            break;
        }
    }
    
    BOOL isStart = (flag & REMOTE_LINE_FLAG_IS_START);
    if (specifiedCommand && isStart)
    {
        [_drawingRemoteCommands removeObject:specifiedCommand];
        specifiedCommand = nil;
    }
    else if (!specifiedCommand && !isStart)
    {
        // ignore the line point without start point
        return;
    }
    
    if (specifiedCommand == nil)
    {
        CGFloat width1 = [self viewWidthFromStandardWidth:width];
        width1 = [self glWidthFromViewWidth:width1];
        
        specifiedCommand = [[DrawingBezierCommand alloc] initWithSequeceId:seqId];
        [specifiedCommand setLineColor:color];
        [specifiedCommand setLineWidth:width1];
        [specifiedCommand setAspect:_canvasAspect];
        
        [_drawingRemoteCommands addObject:specifiedCommand];
    }

    
    for (NSValue *value in pointArray) {
        CGPoint point = [value CGPointValue];
        point = [self viewPointFromStandardPoint:point];
        point = [self glPointFromViewPoint:point];
        [specifiedCommand moveToPoint:point];
    }
    
    BOOL isFinish = (flag & REMOTE_LINE_FLAG_IS_FINISH);
    if (isFinish)
    {
        [specifiedCommand moveEnd];
        NSLog(@"whiteboard line (%d) is drawn, put it into completed commands", specifiedCommand.sequenceId);
        [_completedCommands addObject:specifiedCommand];
    }
    
    
    specifiedCommand.isSaveOnly = (flag & REMOTE_LINE_FLAG_SAVE_ONLY);
    if (!specifiedCommand.isSaveOnly)
    {
        if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
        {
            BOOL isLineGotAll = (flag & REMOTE_LINE_FLAG_IS_GET_ALL);
            if (!isLineGotAll || (isLineGotAll && isFinish))
            {
                [_drawingView setNeedsDisplay];
            }
        }
        [_undoedCommands removeAllObjects];
    }
}

-(void)undoWithSeqId:(int)seqId
{
    for (DrawingBezierCommand *command in _completedCommands)
    {
        if (command.sequenceId == seqId)
        {
            [_undoedCommands addObject:command];
            [_completedCommands removeObject:command];
            
            if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
            {
                bRedrawing = YES;
                [_drawingView setNeedsDisplay];
            }
            
            break;
        }
    }
}

-(void)clear
{
    [_completedCommands removeAllObjects];
    [_drawingRemoteCommands removeAllObjects];
    [_undoedCommands removeAllObjects];
    self.localCommand = nil;
    
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
    {
        bRedrawing = YES;
        [_drawingView setNeedsDisplay];
    }
}

-(void)redoWithSeqId:(int)seqId
{
    for (DrawingBezierCommand *command in _undoedCommands)
    {
        if (command.sequenceId == seqId)
        {
            [_completedCommands addObject:command];
            [_undoedCommands removeObject:command];
            
            if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
            {
                bRedrawing = YES;
                [_drawingView setNeedsDisplay];
            }
            
            break;
        }
    }
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    UIView *hitView = [super hitTest:point withEvent:event];
    CGRect fullSize = [UIScreen mainScreen].bounds;
    
   // 判断当前点在不在按钮上,把当前点转换成按钮所在的坐标系
    CGPoint pencilP = [self convertPoint:point toView:self.pencilBtn];
    CGPoint highlightP = [self convertPoint:point toView:self.highlightBtn];
    CGPoint eraserP = [self convertPoint:point toView:self.eraserBtn];
    CGPoint clearP = [self convertPoint:point toView:self.clearBtn];
    CGPoint colorP = [self convertPoint:point toView:self.colorBtn];
    CGPoint color1P = [self convertPoint:point toView:self.color1Btn];
    CGPoint color2P = [self convertPoint:point toView:self.color2Btn];
    CGPoint color3P = [self convertPoint:point toView:self.color3Btn];
    CGPoint color4P = [self convertPoint:point toView:self.color4Btn];
    CGPoint cancelP = [self convertPoint:point toView:self.cancelColorBtn];
    
    
    if (!self.buttonContainer.hidden) {
        if ([self.pencilBtn pointInside:pencilP withEvent:event] ) {
            return self.self.pencilBtn;
        }else if ([self.highlightBtn pointInside:highlightP withEvent:event] ) {
            return self.self.highlightBtn;
        }else if ([self.eraserBtn pointInside:eraserP withEvent:event] ) {
            return self.self.eraserBtn;
        }else if ([self.clearBtn pointInside:clearP withEvent:event] ) {
            return self.self.clearBtn;
        }else if ([self.colorBtn pointInside:colorP withEvent:event] ) {
            return self.self.colorBtn;
        }
    }else if (!self.colorContainer.hidden) {
        if ([self.color1Btn pointInside:color1P withEvent:event] ) {
            return self.self.color1Btn;
        }else if ([self.color2Btn pointInside:color2P withEvent:event] ) {
            return self.self.color2Btn;
        }else if ([self.color3Btn pointInside:color3P withEvent:event] ) {
            return self.self.color3Btn;
        }else if ([self.color4Btn pointInside:color4P withEvent:event] ) {
            return self.self.color4Btn;
        }else if ([self.cancelColorBtn pointInside:cancelP withEvent:event] ) {
            return self.self.cancelColorBtn;
        }
    }
    return hitView;
}




@end
